import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import Point, Polygon, LineString
from matplotlib.animation import FuncAnimation

class RadarScanner:
    def __init__(self, area_A, radar_pos, angular_res=1):
        """
        参数说明：
        area_A: 目标区域边界 [(x1,y1), (x2,y2), ...]
        radar_pos: 雷达位置 (x, y)
        angular_res: 角度分辨率 (度)
        """
        self.area_A = Polygon(area_A)
        self.radar = Point(radar_pos)
        self.angular_res = angular_res
        self.max_range = 100  # 最大探测距离
        self.scan_results = []
        
        # 验证雷达位置
        if not self.area_A.contains(self.radar):
            print("警告：雷达位于区域外部，可能无法完整扫描边界")

    def single_scan(self):
        """执行完整360度扫描"""
        angles = np.arange(0, 360, self.angular_res)
        boundary_points = []
        
        for angle in angles:
            # 生成射线
            ray = self._create_ray(angle)
            
            # 计算交点
            intersection = self._find_intersection(ray)
            
            if intersection:
                boundary_points.append(intersection)
            else:
                # 添加最大距离点作为占位
                boundary_points.append(self._get_ray_end(angle))
        
        # 构建扫描区域B
        self.area_B = Polygon(boundary_points)
        return boundary_points

    def _create_ray(self, angle):
        """创建探测射线"""
        end = self._get_ray_end(angle)
        return LineString([self.radar, end])

    def _get_ray_end(self, angle):
        """计算射线终点坐标"""
        rad = np.deg2rad(angle)
        dx = self.max_range * np.cos(rad)
        dy = self.max_range * np.sin(rad)
        return Point(self.radar.x + dx, self.radar.y + dy)

    def _find_intersection(self, ray):
        """寻找射线与区域边界的最近交点"""
        if not self.area_A.exterior.intersects(ray):
            return None
        
        intersection = self.area_A.exterior.intersection(ray)
        
        if intersection.is_empty:
            return None
        
        # 获取最近交点
        if intersection.geom_type == 'MultiPoint':
            return min(intersection.geoms, 
                      key=lambda p: self.radar.distance(p))
        return intersection

    def scan_at_angles(self, angles):
        """
        支持输入任意角度列表，返回每个角度下的交点与雷达自身点的距离和交点坐标
        angles: 角度列表（单位：度）
        返回: List[dict]，每个元素包含 {'angle': 角度, 'distance': 距离, 'point': (x, y)}
        """
        results = []
        for angle in angles:
            ray = self._create_ray(angle)
            intersection = self._find_intersection(ray)
            if intersection:
                dist = self.radar.distance(intersection)
                pt = (intersection.x, intersection.y)
            else:
                # 未命中边界，返回最大距离点
                end_pt = self._get_ray_end(angle)
                dist = self.radar.distance(end_pt)
                pt = (end_pt.x, end_pt.y)
            results.append({'angle': angle, 'distance': dist, 'point': pt})
        return results

